import AStarMgr from "./astar/AStarMgr";
import { AstarNodeType } from "./astar/AStarNode";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Main extends cc.Component {

    @property(cc.Graphics)
    graphics: cc.Graphics = null;
    @property(cc.Color)
    colorGrid: cc.Color = null;

    mapW: number;
    mapH: number;
    nodeW: number;
    nodeH: number;
    aStarMgr: AStarMgr;
    startNode: cc.Vec2;
    endNode: cc.Vec2;

    start () {
        this.drawMap();
    }

    onEnable() {
        this.node.on(cc.Node.EventType.TOUCH_END, this.drawTouchNode, this); 
    }

    onDisable() {
        this.node.off(cc.Node.EventType.TOUCH_END, this.drawTouchNode, this); 
    }

    drawMap() {
        this.mapW = 960;
        this.mapH = 640;
        this.nodeW = 40;
        this.nodeH = 40;
        this.aStarMgr = AStarMgr.getInstance();
        this.aStarMgr.initNapInfo(
            this.mapW, 
            this.mapH, 
            this.nodeW, 
            this.nodeH
        );
        this.drawGrid();
    }

    drawTouchNode(event) {
        let node = this.node.convertToNodeSpaceAR(event.getLocation());
        node.x = Math.floor(node.x / this.nodeW);
        node.y = Math.floor(node.y / this.nodeH);
        
        if (this.aStarMgr.isOutBoundary(node.x, node.y)) return;
        let mapNode = this.aStarMgr.nodes[node.x][node.y];
        if (!mapNode || mapNode.type === AstarNodeType.OBSTACLES) return;

        if (this.endNode) {
            this.startNode = null;
            this.endNode = null;
            this.graphics.clear();
            this.drawMap();
            return;
        }

        if (!this.startNode) {
            this.startNode = node;
            this.drawColor(node.x, node.y, cc.Color.ORANGE);
        } else if (!this.endNode) {
            this.endNode = node;
            this.drawColor(node.x, node.y, cc.Color.YELLOW);
            let path = this.aStarMgr.findPath(this.startNode, this.endNode);
            console.log("path", path);
            if (path && path.length > 0) {
                for (let i = 0; i < path.length - 2; i++) {
                    let pnode = path[i];
                    this.drawColor(pnode.x, pnode.y, cc.Color.GREEN);
                }
            }
        }
    }

    drawGrid() {
        this.graphics.strokeColor = this.colorGrid;
        this.graphics.lineWidth = 2;
        let cntW = Math.floor(this.mapW / this.nodeW);
        for (let i = 0; i < cntW; i++) {
            let x = this.nodeW * i;
            this.graphics.moveTo(x, 0)
            this.graphics.lineTo(x, this.mapH);
        }

        let cntH = Math.floor(this.mapH / this.nodeH);
        for (let i = 0; i < cntH; i++) {
            let y = this.nodeH * i;
            this.graphics.moveTo(0, y)
            this.graphics.lineTo(this.mapW, y);
        }

        this.graphics.stroke();

        for (let i = 0; i < this.aStarMgr.mapW; i++) {
            for (let j = 0; j < this.aStarMgr.mapH; j++) {
                let node = this.aStarMgr.nodes[i][j];
                if (node.type === AstarNodeType.OBSTACLES) {
                    this.drawColor(i, j, cc.Color.RED);
                }
            }
        }
     
    }

    drawColor(x: number, y: number, fillColor: cc.Color) {
        this.graphics.fillColor = fillColor;
        this.graphics.rect(x * this.nodeW, y * this.nodeH, this.nodeW, this.nodeH);
        this.graphics.fill();
    }
}
